package com.zone.mybatis.session;

import com.zone.mybatis.binding.MapperRegistry;
import com.zone.mybatis.datasource.druid.DruidDataSourceFactory;
import com.zone.mybatis.executor.Executor;
import com.zone.mybatis.executor.SimpleExecutor;
import com.zone.mybatis.executor.resultset.DefaultResultSetHandler;
import com.zone.mybatis.executor.resultset.ResultSetHandler;
import com.zone.mybatis.executor.statement.PrepareStatementHandler;
import com.zone.mybatis.executor.statement.StatementHandler;
import com.zone.mybatis.mapping.BoundSql;
import com.zone.mybatis.mapping.Environment;
import com.zone.mybatis.mapping.MappedStatement;
import com.zone.mybatis.transaction.Transaction;
import com.zone.mybatis.transaction.jdbc.JdbcTransaction;
import com.zone.mybatis.transaction.jdbc.JdbcTransactionFactory;
import com.zone.mybatis.type.TypeAliasRegistry;

import java.util.HashMap;
import java.util.Map;

/**
 * @author: zongzi
 * @description: TODO
 * @date: 2023/12/17
 */
public class Configuration {

    private Environment environment;

    private final MapperRegistry mapperRegistry = new MapperRegistry();

    private final Map<String, MappedStatement> mappedStatementMap = new HashMap<>();

    private final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();

    public Configuration() {
        typeAliasRegistry.registerAlias("DRUID", DruidDataSourceFactory.class);
        typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
    }

    public MapperRegistry getMapperRegistry() {
        return this.mapperRegistry;
    }


    public Environment getEnvironment() {
        return environment;
    }

    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    public TypeAliasRegistry getTypeAliasRegistry() {
        return typeAliasRegistry;
    }

    public void addMapper(Class<?> type) {
        mapperRegistry.addMapper(type);
    }

    public void addMappedStatement(MappedStatement mappedStatement) {
        mappedStatementMap.put(mappedStatement.getMsId(), mappedStatement);
    }

    public MappedStatement getMappedStatement(String msId) {
        return this.mappedStatementMap.get(msId);
    }

    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return mapperRegistry.getMapper(type, sqlSession);
    }

    public ResultSetHandler getResultSetHandler(BoundSql boundSql) {
        return new DefaultResultSetHandler(boundSql);
    }

    public StatementHandler getStatementHandler(BoundSql boundSql, Object params, ResultSetHandler resultSetHandler) {
        return new PrepareStatementHandler(boundSql, params, resultSetHandler);
    }

    public Executor getExecutor(Transaction transaction) {
        return new SimpleExecutor(this, transaction);
    }
}
